#include "StdAfx.h"
#include "DGame.h"
#include "DWorld.h"
#include "DLoaderThread.h"
#include "../States/GameStates.h"
#include "../Engine/DResourceManagerSFML.h"
#include "../Engine/DIRenderer.h"
#include "../Engine/DInput.h"
#include "../Engine/DAnimation.h"
#include "../Actors/DActorFactory.h"
#include "../Engine/Postprocess/DPostprocessManager.h"

#include "../Actors/DPlayer.h"
#include "../Actors/DBackground.h"

DGame::DGame(boost::shared_ptr<DIRenderer> renderer, 
			 boost::shared_ptr<DInput> input)
: m_renderer(renderer)
, m_input(input)
, m_nCurrentWorldIndex(0)
{
	
}

DGame::~DGame(void)
{
}

bool DGame::init()
{
    m_globalResourceManager.reset(new DResourceManagerSFML);

    bool result = initGlobalResources();
    result &= initGlobalGameObjects();

    changeState(GameStates::Loading::instance());
	return result;
}

void DGame::update(float dt)
{
    m_currentState.lock()->update(dt, shared_from_this());
}

void DGame::render()
{
    m_currentState.lock()->render(shared_from_this());
}

bool DGame::initGlobalResources()
{
    PostprocessManager::instance().init();
    if(!PostprocessManager::instance().isSupported())
    {
        assert(false);
    }

    m_globalResourceManager->loadAnimation("Player/Flying");
    m_globalResourceManager->loadAnimation("Backgrounds/Loading", true);
    m_globalResourceManager->loadAnimation("Bullets/Firebolt");
    return true;
}

bool DGame::initGlobalGameObjects()
{
	m_player = DActorFactory::instance().createPlayer(shared_from_this());
    m_player->setPos(vec2(400, 400));
    m_player->initWeapons();
    return true;
}

void DGame::changeState(boost::shared_ptr<GameStates::IState> newState)
{
    if(m_currentState.lock())
    {
        m_currentState.lock()->exit(shared_from_this());
    }

    m_currentState = newState;
    m_currentState.lock()->enter(shared_from_this());
}

bool DGame::advanceWorld(bool& bLoading)
{
    ++m_nCurrentWorldIndex;
    std::string worldPath = std::string("Data/Game/World") + boost::lexical_cast<std::string>(m_nCurrentWorldIndex) + "/";
    return loadWorld(worldPath, bLoading);
}

bool DGame::loadWorld(const std::string& worldPath, bool& bLoading)
{
    m_world.reset(new DWorld(shared_from_this()));
    m_loader.reset(new DLoaderThread(m_world, worldPath, bLoading));
    m_loader->startLoading();
    return true;
}

boost::shared_ptr<DIRenderer> DGame::renderer() const
{
    return m_renderer;
}

boost::shared_ptr<DIResourceManager> DGame::globalResourceManager() const
{
    return m_globalResourceManager;
}

boost::shared_ptr<DInput> DGame::input() const
{
    return m_input;
}

boost::shared_ptr<DPlayer> DGame::player() const
{
    return m_player;
}

boost::shared_ptr<DWorld> DGame::world() const
{
	return m_world;
}